// File Name: key_interface.c
// Author: kukukukuku~
// Date: 2024-12-24

#include "./Key/inc/key_interface.h"

/**
 * @brief   Key对象初始化
 * @param   keyObj:             Key对象
 * @param   gpio:               Key GPIO对象
 * @param   longPressJudgeNum:  Key长按判断时间
 * @param   pressPolarity:      Key按下的电平
 * @retval  None
 * @note    None
*/
void key_object_init(KEY_OBJECT_T * const keyObj, const KEY_GPIO_OBJECT_T * const gpio, const uint16_t longPressJudgeNum, const uint8_t pressPolarity)
{
    if(keyObj == NULL || gpio == NULL || longPressJudgeNum == 0)
        return;
    
    keyObj->gpio = (KEY_GPIO_OBJECT_T *)gpio;
    keyObj->pressCount = 0;
    keyObj->longPressJudgeCnt = 0;
    keyObj->longPressJudgeNum = longPressJudgeNum;
    keyObj->pressFlag = 0;
    keyObj->longPressScanFlag = 0;
    keyObj->pressPolarity = pressPolarity;
    keyObj->state = KEY_STATE_RELEASE;
    keyObj->handle = KEY_HANDLE_NONE;
}


/**
 * @brief   Key长按扫描中断回调函数
 * @param   keyObj: Key对象
 * @retval  None
 * @note    None
*/
void key_int_long_press_scan_callback(KEY_OBJECT_T * const keyObj)
{
    if(keyObj == NULL)
        return;
    
    //判断是否长按
    if(keyObj->longPressScanFlag && ++(keyObj->longPressJudgeCnt) >= keyObj->longPressJudgeNum)
    {
        keyObj->longPressScanFlag = 0;
        keyObj->longPressJudgeCnt = 0;
        keyObj->handle = KEY_HANDLE_LONG;
    }
}


/**
 * @brief   Key扫描
 * @param   keyObj: Key对象
 * @retval  None
 * @note    None
*/
void key_scan(KEY_OBJECT_T * const keyObj)
{
    if(keyObj == NULL || keyObj->gpio == NULL)
        return;
    
    //Key按下
    if(keyObj->pressFlag == 0 && key_polarity_get(keyObj->gpio) == keyObj->pressPolarity)
    {
        key_delay_ms(15);
        
        //延时15ms后还是按下，则认为按下
        if(key_polarity_get(keyObj->gpio) == keyObj->pressPolarity)
        {
            keyObj->pressFlag = 1;
            keyObj->pressCount++;
            keyObj->state = KEY_STATE_PRESS;
            
            //开始长按扫描
            keyObj->longPressJudgeCnt = 0;
            keyObj->longPressScanFlag = 1;
            key_tmr1_enable();
        }
    }
    //Key松开
    else if(key_polarity_get(keyObj->gpio) != keyObj->pressPolarity)
    {
        keyObj->pressFlag = 0;
        keyObj->longPressScanFlag = 0;
        keyObj->longPressJudgeCnt = 0;
        
        //长按松开清除处理标志，短按松开执行短按处理
        if(keyObj->state == KEY_STATE_PRESS)
            keyObj->handle = keyObj->handle == KEY_HANDLE_LONG ? KEY_HANDLE_NONE : KEY_HANDLE_CLICK;
        
        keyObj->state = KEY_STATE_RELEASE;
    }
}


/**
 * @brief   Key是否触发长按处理
 * @param   keyObj: Key对象
 * @retval  状态
 *          @arg 0: 未触发
 *          @arg 1: 触发
 * @note    None
*/
uint8_t key_is_long_press_triged(KEY_OBJECT_T * const keyObj)
{
    return keyObj == NULL || keyObj->handle != KEY_HANDLE_LONG ? 0 : 1;
}


/**
 * @brief   Key是否触发短按处理
 * @param   keyObj: Key对象
 * @retval  状态
 *          @arg 0: 未触发
 *          @arg 1: 触发
 * @note    None
*/
uint8_t key_is_click_triged(KEY_OBJECT_T * const keyObj)
{
    return keyObj == NULL || keyObj->handle != KEY_HANDLE_CLICK ? 0 : 1;
}


/**
 * @brief   Key清除短按处理标志
 * @param   keyObj: Key对象
 * @retval  None
 * @note    None
*/
void key_clear_click_handle(KEY_OBJECT_T * const keyObj)
{
    if(keyObj == NULL)
        return;
    
    keyObj->handle = KEY_HANDLE_NONE;
}


/**
 * @brief   Key获取长按扫描标志
 * @param   keyObj: Key对象
 * @retval  长按扫描标志
 * @note    None
*/
uint8_t key_long_press_scan_flag_get(KEY_OBJECT_T * const keyObj)
{
    return keyObj == NULL ? 0 : keyObj->longPressScanFlag;
}
